package cn.com.pc.content.dto;

import cn.com.pc.content.util.BeanUtils;
import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;
import org.springframework.data.domain.Page;

import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 分页结果
 * @param <T>
 */

@AllArgsConstructor
@NoArgsConstructor
@Data
@ToString
public class PageResult<T> {
    /**
     * 总数量
     */
    private int total;

    /**
     * 页号
     */
    private int pageNum;

    /**
     * 每页数量
     */
    private int pageSize;

    /**
     * 是否为所有列表
     */
    @JsonIgnore
    private Boolean isAllList = false;

    /**
     * 查询后的结果集
     */
    private List<T> content;

    /**
     * 这个是给查出全部结果集的list用的构造方法
     * @param resultList
     */
    public PageResult(List<T> resultList) {
        this.content = resultList;
        isAllList = true;
        if (resultList != null && !resultList.isEmpty()) {
            total = resultList.size();
        }
    }

    /**
     * 总页数
     * @return
     */
    public int getTotalPage() {
        return total == 0 ? 1 : total / pageSize + (total % pageSize == 0 ? 0 : 1);
    }

    /**
     * 对全部结果集的list查出分页后的结果集
     * @return
     */
    public List<T> getContent() {
        if (isAllList && content != null && !content.isEmpty()) {
            int fromIndex = (pageNum - 1) * pageSize;
            int toIndex = pageNum * pageSize;
            if (fromIndex >= total) {
                return null;
            } else if (toIndex > total) {
                toIndex = total;
            }
            return content.subList(fromIndex, toIndex);
        }
        return content;
    }

    public static <T>PageResult<T> fromPage(Page<T> page){
        return new PageResult<T>((int) page.getTotalElements(), page.getNumber() + 1, page.getSize(), false, page.getContent());
    }

    public static <T, D>PageResult<T> convertContent(PageResult<D> p, Function<D, T> convert) {
        return new PageResult<T>(p.total, p.pageNum, p.pageSize, false, p.getContent().stream().map(convert).collect(Collectors.toList()));
    }

    public static <T, D>PageResult<T> getDtoFromPage(Page<D> page, Function<D, T> convert) {
        return convertContent(fromPage(page), convert);
    }
}
